package com.mystudy.javalambdastudy.stream;

import com.sun.org.apache.xpath.internal.operations.Lt;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.*;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * TODO: {@link Stream}流测试
 * 流由3部分构成：1.源 （stream）； 2.零或者多个中间操作 （惰性求值）； 3.终止操作（及早求值）  stream.xxxx().yyy().zzz().count()
 * 流不存储值，通过管道的方式获取值
 * 本之是函数式的，对流的操作会生成一个结果，不过并不会修改底层的数据源，集合可以作为流的底层数据源
 *
 * @author acy
 * @since 2019/05/05 18:38
 */
public class Java8StreamTest {
	public static void main(String[] args) {
		//IntStream.of(1,2,3).forEach(System.out::println);
		/**
		 * {@link IntStream}类的range方法 获得包含前面，但是不包含后面的元素
		 */
		IntStream.range(3, 8).forEach(System.out::println);
		System.out.println("---------------------");
		/**
		 * {@link IntStream}类的range方法 获得包含前面，包含后面的元素
		 */
		IntStream.rangeClosed(3, 8).forEach(System.out::println);

		List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
		//map接收一个function函数
		list.stream().map(item -> item + 1).reduce(0, Integer::sum);

		Stream<String> stream = Stream.of("acy", "szh", "cy");
		Stream<String> stream1 = Stream.of("acy", "szh", "cy");
		List<String> collect = stream.collect(Collectors.toList());
		//collect   1，创建一个新的list ；2，把stream中的元素加到创建地list里面 3.把所有的创建的list全部都放到一个返回的list里面
		LinkedList<Object> collect1 = stream1.collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
		collect.forEach(System.out::println);
		collect1.forEach(System.out::println);

		//flatMap 将多个集合合并简化成一个
		Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6));
		listStream.flatMap(theList -> theList.stream()).map(item -> item * item).forEach(System.out::println);

		//literate  按照地一定操作对传入的数据进行循环，一般通过limit来限制个数
		Stream<Integer> limit = Stream.iterate(1, item -> item + 2).limit(6);
		//limit.forEach(System.out::println);
		/**
		 * {@link IntSummaryStatistics}
		 * 这里需要吧上面的forEach注释的原因是执行了上面的forEach就会导致流被关闭，下面的就不会执行力
		 */
		IntSummaryStatistics summaryStatistics = limit.filter(item -> item > 2).mapToInt(item -> item + 2).skip(2).limit(2).summaryStatistics();
		System.out.println(summaryStatistics.getSum());

		//groupingBy  分组函数
		GroupByVo cy = new GroupByVo("cy", 23);
		GroupByVo szh = new GroupByVo("szh", 25);
		GroupByVo acy = new GroupByVo("szh", 23);
		List<GroupByVo> groups = Arrays.asList(cy, acy, szh);
		Map<Integer, List<GroupByVo>> listMap = groups.stream().collect(Collectors.groupingBy(GroupByVo::getAge));
		Map<String, Double> stringDoubleMap = groups.stream().collect(Collectors.groupingBy(GroupByVo::getName, Collectors.averagingInt(GroupByVo::getAge)));
		System.out.println(listMap);
		System.out.println(stringDoubleMap);

		//partitioningBy  分区函数
		Map<Boolean, List<GroupByVo>> booleanListMap = groups.stream().collect(Collectors.partitioningBy(item -> item.getAge() > 23));
		System.out.println(booleanListMap);

	}
}

@Getter
@Setter
@AllArgsConstructor
@ToString
class GroupByVo {
	private String name;
	private Integer age;
}
